<template>
  <van-field
    ref="fieldRef"
    v-model="fieldLabel"
    :label="label"
    :label-align="_labelAlign"
    :placeholder="readonly ? '' : `请输入${label}`"
    :readonly="readonly"
    :required="required"
    :rules="rules"
    autocomplete="off"
    clear-trigger="always"
    clearable
    @blur="showPicker = false"
    @clear="onClear"
    @click="!readonly && (showPicker = true)"
  />
  <van-overlay
    :show="showPicker && isNotEmpty(fieldLabel)"
    :style="{ marginTop: offsetTop, marginLeft: offsetLeft, width: overlayWeight }"
    z-index="2002"
    @click="showPicker = false"
  >
    <div style="height: 70vh; overflow: auto">
      <template v-if="props.columnsFieldNames === null">
        <van-cell v-for="item in columns" :key="item" :title="item" @click="onClickItem(item)" />
      </template>
      <template v-else>
        <van-cell
          v-for="item in columns"
          :key="item[props.columnsFieldNames.value]"
          :title="item[props.columnsFieldNames.text]"
          @click="onClickItem(item)"
        />
      </template>
      <van-cell>
        <p class="tip">仅展示前 {{ pageSize }} 条数据</p>
      </van-cell>
    </div>
  </van-overlay>
</template>

<script lang="ts" setup>
import { FieldTextAlign } from 'vant'
import { isNotEmpty } from '../../utils/common'
import _ from 'lodash'
import { QUERY_INTERVAL } from '@/framework/constant'
import { onBeforeMount, Ref } from 'vue'

const props = withDefaults(
  defineProps<{
    modelValue: string | null
    label: string
    columns?: any
    rules?: Array<any>
    required?: boolean
    labelAlign?: FieldTextAlign
    pageSize?: number
    readonly?: boolean
    wrapLength?: number
    interval?: number
    columnsFieldNames?: any
  }>(),
  {
    rules: undefined,
    columns: [],
    labelAlign: 'left',
    pageSize: 30,
    readonly: false,
    wrapLength: 15,
    interval: QUERY_INTERVAL,
    columnsFieldNames: { text: 'label', value: 'value', children: 'children' }
  }
)
const emit = defineEmits<{
  (e: 'update:modelValue', value: string | null): void
  (e: 'getSelectOptions', value: string | null): void
  (e: 'itemClick', value: string | null): void
}>()

const showPicker: Ref<boolean> = ref(false)
const fieldRef: Ref<any> = ref()
const offsetTop = computed(() => {
  return fieldRef.value?.$el.offsetHeight + fieldRef.value?.$el.offsetTop + 'px'
})
const offsetLeft = computed(() => {
  return fieldRef.value?.$el.offsetLeft + 'px'
})
const overlayWeight = computed(() => {
  return fieldRef.value?.$el.weight + 'px'
})
const { columns, label, modelValue, rules, required, labelAlign, pageSize, readonly, wrapLength, interval } =
  toRefs(props)
const _labelAlign = ref(labelAlign.value)
const fieldLabel = ref(modelValue.value)
watch(
  () => fieldLabel.value,
  _.debounce(() => {
    if (modelValue.value) {
      if (modelValue.value.length > wrapLength.value) {
        _labelAlign.value = 'top'
      }
    }
    emit('update:modelValue', fieldLabel.value)

    if (showPicker.value) {
      emit('getSelectOptions', fieldLabel.value)
    }
  }, interval.value),
  {
    immediate: true
  }
)

watch(
  () => modelValue.value,
  () => (fieldLabel.value = modelValue.value)
)

watch(
  () => labelAlign.value,
  () => (_labelAlign.value = labelAlign.value)
)

watch(
  () => showPicker.value,
  () => {
    if (showPicker.value) {
      emit('getSelectOptions', fieldLabel.value)
    }
  }
)
const onClickItem = (item: any) => {
  emit('update:modelValue', props.columnsFieldNames ? item[props.columnsFieldNames.value] : item)
  showPicker.value = false
  emit('itemClick', props.columnsFieldNames ? item[props.columnsFieldNames.value] : item)
}
const onClear = () => {
  emit('update:modelValue', null)
  showPicker.value = false
}
onBeforeMount(() => {})
</script>
